-
Notifications
You must be signed in to change notification settings - Fork 991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix inversion of conditional #4685
Conversation
@RussKie while investigating #4370 I figured out how to host WinForms controls as ActiveX in MFC (which was mostly a problem of MFC being underdocumented and the web starting to forget a lot of docs/examples from the pre- .NET Desktop Framework era; the Desktop Framework docs don't apply since it had special integration via C++/CLI which does not exist for .NET Core so you have to code like you would for non-.NET ActiveX controls, which unfortunately aren't documented well anymore). If you think we should add C++/MFC unit tests covering hosting WinForms controls then I could write some code for that. Really depends on how you want to treat ActiveX compatibility going forward. This particular regression is hard to unit test though, as the method is never called by user code, so any ActiveX unit testing probably should be done separately. |
Codecov Report
@@ Coverage Diff @@
## main #4685 +/- ##
===================================================
- Coverage 97.96413% 97.96388% -0.00025%
===================================================
Files 548 543 -5
Lines 266323 264375 -1948
Branches 5117 4970 -147
===================================================
- Hits 260901 258992 -1909
+ Misses 4529 4499 -30
+ Partials 893 884 -9
Flags with carried forward coverage won't be shown. Click here to find out more. |
Could you share your example? Would love to try testing this out too! |
@hughbe sure, I've created a cleaned up sandbox project here and attached the instructions to create a new project below. Note that you need a custom WinForms build or a recent nightly to get the other (already merged) regression fix from #4370, otherwise the control will not show up. The application breaks into an MFC assert when terminating, I didn't look into that so I don't know who is at fault here, but I guess .NET still has a reference back to a COM interface that hasn't been garbage collected yet. showing an ActiveX control in an MFC applicationFor the managed project:
For the native application:
|
Regression introduced in #2093 |
This would be awesome to have! |
@RussKie sorry, didn't notice you were waiting with the PR for tests. As mentioned above I don't think this regression is testable in an automated fashion and my comment about testing ActiveX was about testing in general, not related to this PR - but if you want to wait with merging until we have a sample scenario to invoke for manual testing I can get to work and add a variant of the sandbox I linked above to the repo (probably a simplified version, there is no reason to use the full blown VS generated template for simple test scenarios). |
Yes, please. A manually run test is just as good. |
Added the test scenario, but encountered some issues (you should be able to run it from VS in the x64 configuration)
|
{3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|Any CPU.ActiveCfg = Debug|x64 | ||
{3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|Any CPU.Build.0 = Debug|x64 | ||
{3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|arm64.ActiveCfg = Debug|x64 | ||
{3129970B-A4EB-46AC-B163-18A5557B11BD}.Debug|arm64.Build.0 = Debug|x64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is weird but consistent with the other native project you're building
@@ -24,6 +24,7 @@ | |||
[assembly: InternalsVisibleTo("MauiRichTextBoxTests, PublicKey=00000000000000000400000000000000")] | |||
[assembly: InternalsVisibleTo("MauiTestsHelper, PublicKey=00000000000000000400000000000000")] | |||
[assembly: InternalsVisibleTo("MauiTabControlTests, PublicKey=00000000000000000400000000000000")] | |||
[assembly: InternalsVisibleTo("NativeHost.ManagedControl, PublicKey=00000000000000000400000000000000")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only necessary because I don't know how to set CompModSwitches
via configuration settings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
App.config did not work? winforms removed dependency but the functionality should be there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it was removed entirely, I'll try if it works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, the instructions don't seem to work. I've tried several variations how to name the .config
file, and I tried it in a standalone managed project instead of a native host, but neither seemed to work. If there are more up to date instructions I'm happy to try again. (And I made sure to also test the instructions on Desktop Framework, there they do indeed work.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange. For this test project, we can keep as-is. I will play around with winforms projects to see if entire config is not working or some sections are not populated.
{ | ||
public ManagedControl() | ||
{ | ||
CompModSwitches.ActiveX.Level = System.Diagnostics.TraceLevel.Verbose; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be better to do this via some configuration, but how?
@@ -13713,7 +13713,7 @@ unsafe HRESULT Ole32.IOleObject.GetMiscStatus(Ole32.DVASPECT dwAspect, Ole32.OLE | |||
return HRESULT.E_POINTER; | |||
} | |||
|
|||
if ((dwAspect & Ole32.DVASPECT.CONTENT) != 0) | |||
if ((dwAspect & Ole32.DVASPECT.CONTENT) == 0) | |||
{ | |||
Debug.WriteLineIf(CompModSwitches.ActiveX.TraceInfo, "AxSource:GetMiscStatus. Status: ERROR, wrong aspect."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug.WriteLineIf(CompModSwitches.ActiveX.TraceInfo, ...);
Note that observing this message without the above fix applied requires a debug build and running in a debugger. It can be tested by running the NativeHost from inside VS (flip the comparison back to test the original regression).
<OutDir>$(ArtifactsBinDir)NativeHost.ManagedControl\$(PlatformTarget)\$(Configuration)\$(TargetFramework)\</OutDir> | ||
<IntDir>$(ArtifactsObjDir)$(ProjectName)\$(PlatformTarget)\$(Configuration)\$(TargetFramework)\</IntDir> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm recognizing artifcats folders. I'm outputting to NativeHost.ManagedControl
to avoid copying the whole MangedControl folder into the NativeHost.
// a clean exit is currently not possible, we would have to force a garbage collection | ||
// to ensure WinForms had a chance to release its COM objects before MFC exits | ||
TerminateProcess(GetCurrentProcess(), S_OK); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In debug builds MFC cannot cleanly shutdown due to hitting an assert, WinForms still has references to MFC. I assume forcing a GC might help, but thats not easily doable. As a workaround I just terminate the process.
Thank you. I was OOF for a week, and I'll try to review this is within fortnight. |
@weltkante , did you get a chance to look at build failures here? |
@dreddy-work I specifically called these out as open issues above, besides other things which don't immediately result in build failures
I don't know how to resolve this myself; maybe this test project just needs to be excluded from CI builds somehow. |
Thanks. I missed part of it. We may need to get help from people who know infra better here. If these tests can be run against X64 successfully, i think we should unblock this PR and limit tests running to X64 arch only until then and open a new issue to track it. |
@jkoritzinsky Why does this work in the non-COM scenario? I've looked at the PR and it seems reasonable but the following statement is concerning without some more context.
|
This works in a non-COM scenario because the "CopyLocalLockFileAssemblies" property is set to true for executable projects, which I believe the other case is (I haven't looked closely at this again recently, but that's my recollection from when I first looked at this) |
@jkoritzinsky So this sounds like yet another one of those cases where a project is actually a self-hosting scenario (e.g., COM server) which is much closer to an EXE than a pure managed assembly project. Is that fair? If so, would it make sense to start building that sort of model in the SDK? |
The failing case here that hits the SDK issues isn't self-hosted though, it's a managed COM DLL that is hosted by a native C++ exe, which we already built a model for in the SDK. The "sdk bug" is a bug in this support we added back in .NET Core 3.x (the bug was probably introduced after 3.x). |
Thank you! With the following change to the managed control project to run the native host again diff --git a/src/System.Windows.Forms/tests/IntegrationTests/NativeHost.ManagedControl/NativeHost.ManagedControl.csproj b/src/System.Windows.Forms/tests/IntegrationTests/NativeHost.ManagedControl/NativeHost.ManagedControl.csproj
index d139f3387..8431433ff 100644
--- a/src/System.Windows.Forms/tests/IntegrationTests/NativeHost.ManagedControl/NativeHost.ManagedControl.csproj
+++ b/src/System.Windows.Forms/tests/IntegrationTests/NativeHost.ManagedControl/NativeHost.ManagedControl.csproj
@@ -14,4 +14,8 @@
<ProjectReference Include="..\..\..\src\System.Windows.Forms.csproj" />
</ItemGroup>
+ <PropertyGroup>
+ <EnableDynamicLoading>true</EnableDynamicLoading>
+ </PropertyGroup>
+
</Project> |
@weltkante can I get you to rebase, and add the following to NativeHost.ManagedControl.csproj, so we can merge it before we branch off for .NET 7.0 <!-- Workaround for https://github.com/dotnet/sdk/pull/19764 -->
<PropertyGroup>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup> |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Thank you! Sorry it took so long. |
Contributes to #4370
Proposed changes
This regression to Desktop Framework was found while investigating #4370. It is unclear what the effects of this regression are, but comparing with Desktop Framework it seems its a mistake from refactoring
When running a debug build of WinForms during investigation of #4370 I had turned on
CompModSwitches.ActiveX
and the broken code resulted in warnings of the ActiveX host passing wrong flags (which of course is wrong, using MFC or Office as host you can assume they pass the right flags).Customer Impact
Regression?
Risk
Before
After
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow